KingDezigns — NAS08 Automated Backup Setup summary

📅 2026-05-11 🖥 NAS08 / Raspberry Pi 5 ⚙️ OpenMediaVault (OMV) 🐳 Docker Compose 💾 ZFS RAIDZ2 — Penta SATA HAT
The goal

NAS08 had no automated recovery path. A software or hardware failure — corrupt SD card, bad OMV update, runaway script — would have required a full manual rebuild of OMV, all Docker containers, Pi-hole, Plex, Vaultwarden, Nextcloud, and nginx-proxy-manager with no documented procedure and no saved state.

No OS backup No automated recovery plan No ZFS restore procedure Plex music library previously lost to a bad script

The goal was to create a fully automated, scheduled backup of the OS and configuration layer — not the NAS data drives — that could restore NAS08 to full operation within approximately 90 minutes after a failure, with no manual intervention during normal operation.

⚠ Critical — store this document off NAS08

Keep a copy of this document on your workstation, a USB drive, or in print. If NAS08 is down you cannot read files stored on it.

Discovery commands run & why
1 Locate Docker app data directories
ls /export/kingdezigns-all/Docker
ls /export/kingdezigns-all/Docker/Compose

Needed to confirm where application configs and compose files lived before writing backup paths into the script.

Docker root confirmed at /export/kingdezigns-all/Docker/ with Compose subfolder containing all stacks: nextcloud, nginx-proxy-manager, pihole, plex, vaultwarden.

2 Check first archive size and contents
ls -lh /export/kingdezigns-all/Backups/NAS08/nas08-backup-2026-05-11.tar.gz
tar -tzf /export/kingdezigns-all/Backups/NAS08/nas08-backup-2026-05-11.tar.gz | head -40

Verified the archive was created and inspected its contents to catch bloat or missing sections.

Archive was 1.4GB — Vaultwarden icon_cache and full Plex config were included without exclusions, inflating the size unnecessarily.

3 Measure sizes across all Docker folders
sudo du -sh /export/kingdezigns-all/Docker/Compose/*/
sudo du -sh /export/kingdezigns-all/Docker/pihole/
sudo du -sh /export/kingdezigns-all/Docker/plex/

Identify where archive bulk was coming from before adding exclusions.

Plex at 1.8GB was the dominant size. Pi-hole at 27MB acceptable as-is. Compose folders were tiny (3.5K–7.4M each).

4 Drill into Plex config subfolder breakdown
sudo du -sh /export/kingdezigns-all/Docker/plex/config/Library/Application\ Support/Plex\ Media\ Server/*/

Identify which Plex subfolders were safe to exclude vs which contained manually curated data worth preserving.

Cache (24M), Logs (2M), Crash Reports (23K) identified as safe exclusions. Media (655M) and Metadata (956M) confirmed as music organization and library data — kept.

5 Inspect ZFS pool configuration
sudo zpool list
sudo zpool status
sudo zfs list

Document exact pool name, drive identifiers, RAID type, and mount point needed for recovery plan ZFS steps.

Pool: kingdezignsnas — RAIDZ2 across 4 × 1TB SSDs — ONLINE — mounted at /kingdezignsnas — last scrub clean, no errors.

Issues encountered during setup

On first run the backup destination directory did not exist, causing the logging system to fail immediately before any backup work could begin.

⚠ Error — first run

Script failed with a tee write error before reaching any backup steps.

tee: /export/kingdezigns-all/Backups/NAS08/backup.log: No such file or directory

Backups/NAS08/ had not been created yet. Fixed by creating it manually. The script now handles this automatically via mkdir -p on every run.

SCP to /usr/local/bin/ failed with permission denied — that path requires root SCP access which rufusking does not have.

Resolution: Created /usr/scripts/omv/ owned by rufusking. SCP now works without root. Script still runs with sudo for root-level operations at runtime.

Scripts / files created
Backup Script Location
/usr/scripts/omv/nas08-backup.sh
What It Backs Up
OMV config        — omv-confbak export + raw /etc/openmediavault/config.xml
/etc              — full system config (network, fstab, nginx, cron, etc.)
Docker Compose    — all stacks + global.env  (vaultwarden icon_cache excluded)
Pi-hole data      — /export/kingdezigns-all/Docker/pihole/
Plex data         — full config minus Cache/, Logs/, Crash Reports/
                    Media/ and Metadata/ KEPT (music org + library data)
Shared folder     — /export/kingdezigns-all/Docker/Shared/
Crontab           — root crontab + /etc/cron.d entries
MANIFEST.txt      — baked-in restore instructions and OMV version info
Output Paths
/export/kingdezigns-all/Backups/NAS08/nas08-backup-YYYY-MM-DD.tar.gz
/export/kingdezigns-all/Backups/NAS08/backup.log
Retention
10 archives retained (~30 days coverage) — older archives auto-deleted on each run
Expected Size
~1.4GB per archive — ~14GB total at max retention
450GB free on data drive — well within capacity
Schedule via OMV UI
System → Scheduled Jobs → Add
  Name:          NAS08 Backup
  Command:       /usr/scripts/omv/nas08-backup.sh
  Minute:        0
  Hour:          2
  Day of month:  */3
  Month:         *
  Day of week:   *
Runs automatically at 2:00 AM every 3 days
Manual Run
sudo /usr/scripts/omv/nas08-backup.sh
# or: OMV UI → System → Scheduled Jobs → Run
Full recovery procedure
⚠ Before You Start

You need: a workstation with internet, a replacement SD card (16GB+), Raspberry Pi Imager, SSH access, and your rufusking password. Physically connect all 4 ZFS drives to the Penta SATA HAT before powering on.

Phase 1 — Flash the OS
1 Download Raspberry Pi Imager — workstation
https://www.raspberrypi.com/software/

Download and install for your OS (Windows / Mac / Linux).

2 Flash Raspberry Pi OS Lite (64-bit) — workstation
Open Raspberry Pi Imager
→ Choose Device    : Raspberry Pi 5
→ Choose OS        : Raspberry Pi OS Lite (64-bit)   ← NOT the Desktop version
→ Choose Storage   : your SD card
→ Next → Edit Settings:
    Hostname  : NAS08
    Username  : rufusking
    Password  : your usual password
    Services  : Enable SSH → Use password authentication
→ Save → Yes → Yes (confirm flash and verify)

Wait for the flash and verify to complete fully before removing the SD card.

3 Boot the Raspberry Pi
1. Insert SD card into Raspberry Pi 5
2. Connect Penta SATA HAT with all 4 ZFS drives plugged in
3. Power on
4. Wait 2–3 minutes for first boot to complete
Phase 2 — Install OpenMediaVault
⚠ Note

The OMV install method may change in the future. Verify the current script at https://github.com/OpenMediaVault-Plugin-Developers/installScript before running. Steps below reflect the method as of 2026-05-11.

4 SSH into NAS08 — workstation
ssh rufusking@192.168.150.35

If the static IP is not yet assigned, log into UniFi at http://192.168.100.1, find NAS08 in Clients, and SSH to its temporary IP instead.

5 Update the OS — NAS08
sudo apt-get update && sudo apt-get upgrade -y

Wait for the prompt to return before continuing. This may take a few minutes.

6 Install OpenMediaVault — NAS08
sudo wget -O - https://github.com/OpenMediaVault-Plugin-Developers/installScript/raw/master/install | sudo bash

Takes 10–20 minutes. The Pi may reboot automatically. If it does, SSH back in and wait for the script to finish. Do not interrupt it.

7 Verify OMV is running — browser on workstation
http://192.168.150.35

Default login:
  Username: admin
  Password: openmediavault

Confirm the OMV login page loads. Do not configure anything yet — the restore handles all configuration.

Phase 3 — Enable PCIe for Penta SATA HAT

The Raspberry Pi 5 does not expose PCIe by default. Without enabling it, the Penta SATA HAT and all 4 ZFS drives are completely invisible to the OS. This must be done before any ZFS commands will work.

8 Edit boot config to enable PCIe — NAS08
sudo nano /boot/firmware/config.txt

Scroll to find the line arm_boost=1 and add these lines immediately after it:

# Enable PCIe
dtparam=pciex1
dtparam=pciex1_gen=3

Save and exit:

Ctrl+X  →  Y  →  Enter
9 Reboot to apply PCIe config — NAS08
sudo reboot

Wait 2–3 minutes, then SSH back in:

ssh rufusking@192.168.150.35
Phase 4 — Import ZFS Pool
10 Install ZFS tools — NAS08
sudo apt-get install -y zfsutils-linux

Installs the ZFS kernel modules and CLI tools. Required on every fresh OS install.

11 Verify all 4 drives are visible — NAS08
lsblk

You should see 4 drives listed (typically sda through sdd). If any are missing, check physical connections and reboot:

sudo reboot
# SSH back in, then run lsblk again
12 Import the ZFS pool — NAS08
sudo zpool import kingdezignsnas

The pool name kingdezignsnas is stored on the drives themselves — it will be recognized on a fresh OS automatically. If the previous OS failed uncleanly, force the import:

# Only use -f if the standard import fails:
sudo zpool import -f kingdezignsnas
13 Verify pool imported correctly — NAS08
sudo zpool status

All 4 drives must show ONLINE. Expected output:

  pool: kingdezignsnas
 state: ONLINE
config:
    kingdezignsnas                        ONLINE
      raidz2-0                            ONLINE
        ata-CT1000BX500SSD1_2539E9CB8529  ONLINE
        ata-CT1000BX500SSD1_2534E9C97DAD  ONLINE
        ata-CT1000BX500SSD1_2530E9C74CD1  ONLINE
        ata-CT1000BX500SSD1_2539E9CB84F8  ONLINE
errors: No known data errors

If any drive shows FAULTED or DEGRADED, do not proceed. See ZFS Troubleshooting at the bottom of this document.

14 Confirm backup files are accessible — NAS08
sudo zfs list
ls /kingdezignsnas/
ls /kingdezignsnas/Backups/NAS08/

# List archives sorted newest first:
ls -lht /kingdezignsnas/Backups/NAS08/nas08-backup-*.tar.gz

Use /kingdezignsnas/ directly at this stage. The /export/kingdezigns-all/ path is recreated by OMV after the config restore in Phase 6.

Phase 5 — Extract the Backup Archive
15 Create restore working directory — NAS08
sudo mkdir -p /tmp/nas08-restore
16 Extract the most recent backup — NAS08
# Replace YYYY-MM-DD with the actual archive date from step 14
sudo tar -xzf /kingdezignsnas/Backups/NAS08/nas08-backup-YYYY-MM-DD.tar.gz \
    -C /tmp/nas08-restore

This takes a few minutes — the archive is ~1.4GB. Wait for the prompt to return.

17 Confirm extraction and read the manifest — NAS08
# Confirm all folders are present:
ls /tmp/nas08-restore/
ls /tmp/nas08-restore/nas08-backup-*/

# Read the manifest:
cat /tmp/nas08-restore/nas08-backup-*/MANIFEST.txt

You should see: omv-config/  etc/  docker-compose/  app-data/  cron/  MANIFEST.txt

Phase 6 — Restore System Configuration
18 Restore /etc — NAS08
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/etc/ /etc/

Restores all system configuration: network settings, nginx, fstab, cron, and everything else under /etc.

19 Restore OMV configuration — NAS08
# Copy saved OMV config back into place:
sudo cp /tmp/nas08-restore/nas08-backup-*/omv-config/config.xml.raw \
    /etc/openmediavault/config.xml

# Load it into the OMV database:
sudo omv-confdbadm populate

# Re-apply all settings to the system (shares, users, plugins, schedules):
sudo omv-salt deploy run all

The last command takes several minutes. Do not interrupt it — let it complete fully.

20 Reboot and verify OMV — NAS08 then browser
sudo reboot

After 2–3 minutes, SSH back in and check:

ssh rufusking@192.168.150.35

Then open a browser on your workstation:

http://192.168.150.35

Log in and verify: shares, users, and settings are present. Go to Storage → File Systems and confirm the ZFS pool is mounted and /export/kingdezigns-all is available.

Phase 7 — Restore Docker and Application Data
21 Verify Docker is installed — NAS08
sudo docker ps

If Docker is not found, install it:

sudo apt-get install -y docker-compose-plugin

If the OMV Compose plugin is missing, reinstall via OMV UI:

OMV UI → System → Plugins → search "compose" → Install
22 Restore Docker Compose files — NAS08
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/docker-compose/ \
    /export/kingdezigns-all/Docker/Compose/

# Verify files landed correctly:
ls /export/kingdezigns-all/Docker/Compose/

Expected: nextcloud/  nginx-proxy-manager/  pihole/  plex/  vaultwarden/  global.env

23 Restore Pi-hole data — NAS08
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/app-data/pihole/ \
    /export/kingdezigns-all/Docker/pihole/
24 Restore Plex data — NAS08
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/app-data/plex/ \
    /export/kingdezigns-all/Docker/plex/

This restores your music organization (Media/), library metadata (Metadata/), and watch history (Plug-in Support/). These are the folders that represent weeks of manual work and are the primary reason this backup exists.

25 Restore Shared folder — NAS08
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/app-data/shared/ \
    /export/kingdezigns-all/Docker/Shared/
26 Fix permissions on all Docker folders — NAS08
sudo chown -R root:users /export/kingdezigns-all/Docker/
sudo chmod -R 775 /export/kingdezigns-all/Docker/
Phase 8 — Bring Containers Back Up
27 Start each container one at a time — NAS08
cd /export/kingdezigns-all/Docker/Compose/pihole && sudo docker compose up -d
cd /export/kingdezigns-all/Docker/Compose/nginx-proxy-manager && sudo docker compose up -d
cd /export/kingdezigns-all/Docker/Compose/vaultwarden && sudo docker compose up -d
cd /export/kingdezigns-all/Docker/Compose/nextcloud && sudo docker compose up -d
cd /export/kingdezigns-all/Docker/Compose/plex && sudo docker compose up -d

Start one at a time — not all at once — so errors from individual containers are not lost in combined output.

28 Verify all containers are running — NAS08
sudo docker ps

All containers should show status Up. If any show Exited, check that container's logs:

sudo docker logs pihole
sudo docker logs nginx-proxy-manager
sudo docker logs vaultwarden
sudo docker logs nextcloud
sudo docker logs plex
Phase 9 — Final Steps & Verification
29 Verify the backup script is in place — NAS08
ls -lh /usr/scripts/omv/nas08-backup.sh

If missing (it lives outside /etc so may not have restored automatically), copy it from your workstation:

# On your workstation:
scp nas08-backup.sh rufusking@192.168.150.35:/usr/scripts/omv/nas08-backup.sh

# On NAS08:
chmod +x /usr/scripts/omv/nas08-backup.sh
30 Restore the crontab — NAS08
sudo crontab /tmp/nas08-restore/nas08-backup-*/cron/root-crontab.txt

# Verify it was applied:
sudo crontab -l
31 Reschedule the backup job in OMV UI
OMV UI → System → Scheduled Jobs → Add
  Enabled:       Yes
  Name:          NAS08 Backup
  Command:       /usr/scripts/omv/nas08-backup.sh
  Minute:        0
  Hour:          2
  Day of month:  */3
  Month:         *
  Day of week:   *
→ Save
32 Clean up the restore working directory — NAS08
sudo rm -rf /tmp/nas08-restore
33 Run a fresh backup immediately to create a new baseline
# Option A — OMV UI:
System → Scheduled Jobs → NAS08 Backup → Run

# Option B — SSH on NAS08:
sudo /usr/scripts/omv/nas08-backup.sh

# Verify it completed successfully:
ls -lh /export/kingdezigns-all/Backups/NAS08/
cat /export/kingdezigns-all/Backups/NAS08/backup.log
34 Run a ZFS scrub to verify data integrity — NAS08
sudo zpool scrub kingdezignsnas

# Check results a few minutes later:
sudo zpool status

A healthy result:

scan: scrub repaired 0B in 00:xx:xx with 0 errors
ZFS Troubleshooting
— Pool shows DEGRADED — 1 drive failed
sudo zpool status   ← failed drive shows FAULTED or UNAVAIL

RAIDZ2 tolerates up to 2 simultaneous drive failures. The pool is still fully readable and writable. Complete the full restore procedure first, then replace the failed drive. Do not skip recovery steps.

— Pool shows DEGRADED — 2 drives failed
sudo zpool status   ← two drives show FAULTED or UNAVAIL

Data is at risk but still accessible. Complete the restore immediately and replace both drives as fast as possible. Seek assistance before doing anything else if unsure.

— Pool cannot be imported — not found
# Scan all connected devices for importable pools:
sudo zpool import

# If kingdezignsnas appears in the list, force import:
sudo zpool import -f kingdezignsnas

If no pools are found at all, PCIe is likely not enabled. Verify Steps 8–9 (boot config) were applied correctly and reboot again before retrying.

— Pool imported but /export/kingdezigns-all is missing
# Access backup files directly via the ZFS mount point:
ls /kingdezignsnas/Backups/NAS08/

/export/kingdezigns-all/ is created by OMV when it mounts the filesystem. Use /kingdezignsnas/ as the base path for all restore commands until OMV is fully restored.

Lessons learned
LessonDetail
PCIe must be enabled before ZFS can see the drives The Raspberry Pi 5 Penta SATA HAT requires PCIe to be explicitly enabled in /boot/firmware/config.txt. On a fresh OS this is never set. Without it all 4 ZFS drives are invisible and the pool cannot be imported.
ZFS pool import must happen before any restore steps Without importing the pool, the backup files are completely inaccessible. It is now Phase 4, immediately after enabling PCIe, before any restore work begins.
Plex Media/ and Metadata/ contain irreplaceable manually curated data These folders hold music organization, artwork, and library structure that took weeks of manual work. They must always be included in backups even though they are large (~1.6GB combined).
Never run scripts that touch OMV without a tested recovery plan first A prior script run by another AI tool broke OMV and wiped Plex music organization. This session was motivated by that incident. Backup first, change second.
Custom scripts belong in /usr/scripts/ not /usr/local/bin/ Writing to /usr/local/bin/ requires root SCP access. A dedicated /usr/scripts/ directory owned by rufusking avoids this and keeps custom scripts separated from system binaries.
Always create output directories before the first script run The script failed on first run because /Backups/NAS08/ did not exist. The script now handles this automatically via mkdir -p, but always verify the path exists before the first run on a new system.
Vaultwarden icon_cache is large and completely disposable The icon cache for website favicons was inflating the archive. It regenerates automatically and must always be excluded.
Recovery documentation must be stored off the device being recovered A recovery plan stored only on NAS08 is useless when NAS08 is down. Keep copies on a workstation, USB drive, or in print.
Network map — items to update
ItemOld valueNew value
NAS08 — Hardware detail Raspberry Pi Raspberry Pi 5 with Penta SATA HAT
NAS08 — Backup status None Automated — every 3 days — 30-day retention
NAS08 — Backup destination None /export/kingdezigns-all/Backups/NAS08/
NAS08 — Backup script None /usr/scripts/omv/nas08-backup.sh
NAS08 — ZFS pool name not documented kingdezignsnas (RAIDZ2, 4 × 1TB SSD)
NAS08 — ZFS mount point not documented /kingdezignsnas
NAS08 — PCIe requirement not documented dtparam=pciex1 + dtparam=pciex1_gen=3 required in /boot/firmware/config.txt on fresh OS
NAS08 — Recovery plan None NAS08-Backup-Summary.html — 34 steps across 9 phases + ZFS troubleshooting